/*
* Copyright 2005-2008 Pulse Technologies. Tutti i diritti riservati.
*/
package org.obsidianrad.server.services.obj2db.dao;


import java.lang.reflect.Array;
import java.util.List;

import org.obsidianrad.server.services.ObsModel;
import org.obsidianrad.server.services.obj2db.commodities.BasePagingLoadResult;
import org.obsidianrad.server.services.obj2db.commodities.Filterer;
import org.obsidianrad.server.services.obj2db.commodities.PagingLoadConfig;
import org.obsidianrad.server.services.obj2db.commodities.PagingLoadResult;
import org.obsidianrad.utils.ObjProxyException;
import org.springframework.orm.ibatis.support.SqlMapClientDaoSupport;

/**
 * 
 * @author Eligio Colutta
 * @version $Rev: 4 $
 * @lastautorcommit $Author: eliosh $
 * @lastdatecommit $Date: 2009-10-31 12:37:28 +0100(sab, 31 ott 2009) $
 */
public abstract class GenericDAOImpl<T extends ObsModel> extends SqlMapClientDaoSupport implements GenericDAO<T>{

	@Override
	public Integer deleteMany(Filterer reference) throws ObjProxyException {
		if(getDeleteManyMapName()==null){
			throw new ObjProxyException("getDeleteManyMapName() return null string");
		}
		return getSqlMapClientTemplate().delete(getDeleteManyMapName(), reference);
	}
	
	@Override
	public void deleteOne(T reference) throws ObjProxyException {
		if(getDeleteOneMapName()==null){
			throw new ObjProxyException("getDeleteOneMapName() return null string");
		}
		getSqlMapClientTemplate().delete(getDeleteOneMapName(), reference, 1);
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public PagingLoadResult<T> getList(T reference, PagingLoadConfig config) throws ObjProxyException {
		if(this.getListCountMapName()==null){
			throw new ObjProxyException("getListCountMapName() return null string");
		}else if(this.getListMapName()==null){
			throw new ObjProxyException("getListMapName() return null string");
		}
		List<T> sublist = getSqlMapClientTemplate().queryForList(this.getListMapName(), reference, config.getOffset(), config.getLimit());
		Integer count = (Integer) getSqlMapClientTemplate().queryForObject(this.getListCountMapName(), reference);
		T[] subListAsArray = null;
		if(sublist.size()>0){
			subListAsArray = (T[]) Array.newInstance(reference.getClass() , sublist.size()); //new Object[sublist.size()];
			sublist.toArray(subListAsArray);
		}
		return new BasePagingLoadResult<T>(subListAsArray, config.getOffset(), count.intValue());
		
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public PagingLoadResult<T> getList(Filterer reference, PagingLoadConfig config) throws ObjProxyException {
		if(this.getCriteriaListCountMapName()==null){
			throw new ObjProxyException("getCriteriaListCountMapName() return null string");
		}else if(this.getCriteriaListMapName()==null){
			throw new ObjProxyException("getCriteriaListMapName() return null string");
		}
		// Filterer reference = config.getFilterer();
		List<T> sublist = getSqlMapClientTemplate().queryForList(this.getCriteriaListMapName(), reference, config.getOffset(), config.getLimit());
		Integer count = (Integer) getSqlMapClientTemplate().queryForObject(this.getCriteriaListCountMapName(), reference);
		T[] subListAsArray = null;
		if(sublist.size()>0){
			T test = sublist.get(0);
			Class clazz = (test.getSuperclass()!=null?test.getSuperclass():test.getClass());
			subListAsArray = (T[]) Array.newInstance(clazz, sublist.size()); //new Object[sublist.size()];
			sublist.toArray(subListAsArray);
		}
		return new BasePagingLoadResult<T>(subListAsArray, config.getOffset(), count.intValue());
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public T getSingle(T reference) throws ObjProxyException {
		if(getSingleMapName()==null){
			throw new ObjProxyException("getSingleMapName() return null string");
		}else if(reference.getPKey()==null){
			throw new ObjProxyException("La ricerca del singolo elemento va effettuata ESCLUSIVAMENTE via primary key.");
		}
		return (T) getSqlMapClientTemplate().queryForObject(getSingleMapName(), reference);
	}
	
	@Override
	public String save(T reference) throws ObjProxyException {
		if(getSaveMapName()==null){
			throw new ObjProxyException("getSaveMapName() return null string");
		}
		return (String) getSqlMapClientTemplate().insert(getSaveMapName(), reference);
	}
	
	@Override
	public T updateOne(T reference) throws ObjProxyException {
		if(getUpdateOneMapName()==null){
			throw new ObjProxyException("getUpdateOneMapName() return null string");
		}else if(reference.getPKey()==null){
			throw new ObjProxyException("L'aggiornamento del singolo elemento va effettuata ESCLUSIVAMENTE se presente una primary key.");
		}
		getSqlMapClientTemplate().update(getUpdateOneMapName(), reference, 1);
		return this.getSingle(reference);
	}
	
	@Override
	public int updateMany(Filterer reference) throws ObjProxyException {
		if(getUpdateManyMapName()==null){
			throw new ObjProxyException("getUpdateManyMapName() return null string");
		}
		return getSqlMapClientTemplate().update(getUpdateManyMapName(), reference);
	}
	
	
}
